package umls.geneus.core;

import java.io.IOException;
import java.net.MalformedURLException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import umls.Metamap.MetamapClient;
import umls.expander.GenKeywords;
import umls.geneus.core.data.PubmedScanner;

public class Geneus {

	private static Logger logger;
	private PubmedScanner pscan;
	private MetamapClient mc;
	private Config config;
	public Geneus(Config c){
		 logger = Logger.getLogger(Geneus.class);
		 this.config=c;
		 try {
			mc = new MetamapClient( config.getMetamapHost());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e){
			logger.error("No metamap server found on address "+ config.getMetamapHost());
		}
	}
	
	
	public List<String> expandedSearch(String process, String gene, List<String> expanGroups){
		GenKeywords expander = new GenKeywords("./confsem.txt",expanGroups);
		List<String>related_words= null;
		try {
			related_words = expander.generate(gene, process);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		List<String> totalresults= new LinkedList<String>();
	//	related_words.subList(fromIndex, toIndex)
		for (String word:related_words){
			List<String> partialids= searchPubmedIds(new String[]{process,gene,word});
			if (partialids.size()==0){
				partialids= searchPubmedIds(new String[]{process,word});
				partialids.addAll(searchPubmedIds(new String[]{gene,word}));
			}
			totalresults.addAll(partialids);
		}
		return totalresults;
	}
	
	public List<String> searchPubmedIds(String[] input){
		if (input == null || input.length ==0 ){
			logger.warn("Pubmed scan with 0 inputs detected, returning empty resultset");
			return new ArrayList<String>(0);
		}
		List<String> ids = null;
		try {
			ids= pscan.getPubmedIds(input);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ids;
		
	}
	
	public Future<List<String>>  searchPubmedIdsAsync(String[] input){
		if (input == null || input.length ==0 ){
			logger.warn("Pubmed scan with 0 inputs detected, returning empty resultset");
			return null;
		}
		List<String> ids = null;
		try {
			ids= pscan.getPubmedIds(input);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	
	public void setPscanner(PubmedScanner pscan) {
		this.pscan = pscan;
	}
	
	public String getDocument(String id){
		if (id==null || id.equals("")){
			logger.warn("Tried to retrieve a document with empty id");
			return "";
		}
		String result = null;
		try {
			result = pscan.getPubmedAbstract(id);
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	
	public List<String> getMappedDocument(String id){
		String doc = getDocument(id);
		if (doc==null || doc.equals("")){
			logger.warn("empty document mapping blocked");
		}
		List<String> mapped= mc.blockingQuery(doc, null);
		return mapped;
	}
	public Config getConfig() {
		return config;
	}
	public void setConfig(Config config) {
		this.config = config;
	}


	
}
